/**
**********************************************************************
* @file     main.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2024-05-25 14:27:29
* @copyright Copyright &copy; 2024 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
**********************************************************************
* @note
* None.
**********************************************************************
* @attention
* None.
**********************************************************************
@verbatim
@endverbatim
**********************************************************************
* @par 历史记录
* 1. v0.0.1: jcai, 2024-05-25 14:27:29
*   - 首次编写
*
*<center>Copyright &copy; 2024 wy1107412334@163.com All rights reserved</center>
**********************************************************************
*/

/* 头文件导入区 --------------------------------------------------- */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>


/** @defgroup MAIN MAIN
* @brief main modules
* @{
*/



/*********************************************************************
                私有宏定义
*********************************************************************/

#define WIN_X_POS                               0
#define WIN_Y_POS                               0
#define WIN_WIDTH                               640
#define WIN_HIGHT                               480

#define TILE_SIZE                               80





/*********************************************************************
                私有数据类型声明
*********************************************************************/








/*********************************************************************
                私有变量定义
*********************************************************************/





/** @defgroup MAIN_Exported_Variables main exported variables
* @brief 全局变量定义
* @{
*/



/** defgroup MAIN_Exported_Variables
* @}
*/





/*********************************************************************
                私有函数定义
*********************************************************************/

static void outSDLError(const char * msg)
{
    fprintf(stderr, "%s error: %s\n", msg, SDL_GetError());
}
static void outSDLImgError(const char * msg)
{
    fprintf(stderr, "%s error: %s\n", msg, IMG_GetError());
}

static SDL_Texture * loadImg2Texture(const char * filepath, SDL_Renderer * sdlrd)
{
    SDL_Texture * texture = IMG_LoadTexture(sdlrd, filepath);
    if (texture == NULL)
    {
        outSDLImgError("IMG_LoadTexture()");
    }
    return texture;
}

static void renderTextureRect(SDL_Texture * tex, SDL_Renderer * sdlrd, int x, int y, int w, int h)
{
    SDL_Rect dst;

    dst.x = x;
    dst.y = y;
    dst.w = w;
    dst.h = h;

    SDL_RenderCopy(sdlrd, tex, NULL, &dst);
}

static void renderTexture(SDL_Texture * tex, SDL_Renderer * sdlrd, int x, int y)
{
    int w, h;
    SDL_QueryTexture(tex, NULL, NULL, &w, &h);
    renderTextureRect(tex, sdlrd, x, y, w, h);
}








/** @defgroup MAIN_Exported_Functions main exported functions
* @brief 全局函数定义
* @{
*/



/**
**********************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
int main(int argc, char *argv[])
{
    (void) argc;
    (void) argv;

    if (SDL_Init(SDL_INIT_VIDEO) != 0)
    {
        outSDLError("SDL_Init()");
        goto initRet;
    }

    if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
    {
        outSDLImgError("IMG_Init()");
        goto initRet;
    }

    SDL_Window * sdlwin = SDL_CreateWindow("title", WIN_X_POS, WIN_Y_POS, WIN_WIDTH, WIN_HIGHT, SDL_WINDOW_SHOWN);
    if (sdlwin == NULL)
    {
        outSDLError("SDL_CreateWindow()");
        goto winRet;
    }

    SDL_Renderer * sdlrd = SDL_CreateRenderer(sdlwin, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    if (sdlrd == NULL)
    {
        outSDLError("SDL_CreateRenderer()");
        goto renderRet;
    }


    SDL_Texture * image = loadImg2Texture("./image.png", sdlrd);
    if (image == NULL)
    {
        outSDLError("load image \"image.bmp\" failed.");
        goto textureRet;
    }


    int iW, iH;
    SDL_QueryTexture(image, NULL, NULL, &iW, &iH);
    int x = (WIN_WIDTH / 2) - (iW / 2);
    int y = (WIN_HIGHT / 2) - (iH / 2);


    SDL_Event e;
    int quit = 0;
    while (!quit)
    {
        while (SDL_PollEvent(&e))
        {
            int keyState = 0;
            switch (e.type)
            {
            case SDL_QUIT:
#if 0
            case SDL_KEYDOWN:
            case SDL_MOUSEBUTTONDOWN:
#endif
                quit = 1;
                break;

            case SDL_KEYDOWN:
                keyState = 1;
                break;
            case SDL_KEYUP:
                keyState = 2;
                break;
            }

            if (keyState)
            {
                int valueType = 0;
                int key = e.key.keysym.sym;

                switch (key)
                {
                case SDLK_0 ... SDLK_9:
                    valueType = 1;  // 数字类型

                    if ((!(e.key.keysym.mod & KMOD_CTRL)) &&
                        (!(e.key.keysym.mod & KMOD_ALT)) &&
                        (!(e.key.keysym.mod & KMOD_GUI)) &&
                        (e.key.keysym.mod & KMOD_SHIFT))
                    {
                        int symOnNum[] = {SDLK_RIGHTPAREN, SDLK_EXCLAIM, SDLK_AT,
                                          SDLK_HASH, SDLK_DOLLAR, SDLK_PERCENT,
                                          SDLK_CARET, SDLK_AMPERSAND, SDLK_ASTERISK,
                                          SDLK_LEFTPAREN};
                        valueType = 3;  // 符号
                        key = symOnNum[key - SDLK_0];
                    }
                    break;

                case SDLK_a ... SDLK_z:
                    valueType = 2;  // 字母类型

                    if ((!(e.key.keysym.mod & KMOD_CTRL)) &&
                        (!(e.key.keysym.mod & KMOD_ALT)) &&
                        (!(e.key.keysym.mod & KMOD_GUI)) &&
                        ((e.key.keysym.mod & KMOD_SHIFT) || (e.key.keysym.mod & KMOD_CAPS)))
                    {
                        if ((e.key.keysym.mod & KMOD_CAPS) && (e.key.keysym.mod & KMOD_SHIFT))
                        {
                            // 什么都不做，因为SDL2默认都是小写字母
                        }
                        else
                        {
                            // 小写字母转大写字母
                            key -= 0x20;
                        }
                    }
                    break;

                case SDLK_TAB:
                case SDLK_SPACE ... SDLK_SLASH:
                case SDLK_COLON ... SDLK_AT:
                case SDLK_LEFTBRACKET ... SDLK_BACKQUOTE:
                    valueType = 3;  // 符号
                    break;
                }

                if ((valueType == 3) &&
                    (!(e.key.keysym.mod & KMOD_CTRL)) &&
                    (!(e.key.keysym.mod & KMOD_ALT)) &&
                    (!(e.key.keysym.mod & KMOD_GUI)) &&
                    (e.key.keysym.mod & KMOD_SHIFT))
                {
                    switch (key)
                    {
                    case SDLK_BACKQUOTE:    // '`'
                        key = '~';
                        break;
                    case SDLK_MINUS:        // '-'
                        key = SDLK_UNDERSCORE;
                        break;
                    case SDLK_EQUALS:       // '='
                        key = SDLK_PLUS;
                        break;
                    case SDLK_LEFTBRACKET:  // '['
                        key = '{';
                        break;
                    case SDLK_RIGHTBRACKET: // ']'
                        key = '}';
                        break;
                    case SDLK_BACKSLASH:    // '\'
                        key = '|';
                        break;
                    case SDLK_SEMICOLON:    // ';'
                        key = SDLK_COLON;
                        break;
                    case SDLK_QUOTE:        // '''
                        key = SDLK_QUOTEDBL;
                        break;
                    case SDLK_COMMA:        // ','
                        key = SDLK_LESS;
                        break;
                    case SDLK_PERIOD:       // '.'
                        key = SDLK_GREATER;
                        break;
                    case SDLK_SLASH:       // '/'
                        key = SDLK_QUESTION;
                        break;
                    default:
                        break;
                    }
                }

                if (valueType)
                {
                    printf("%s: e.key.keysym.scancode: %d, e.key.keysym.sym: %d(%c), e.key.keysym.mod: %d; "
                           "Ctrl key: %d, Alt key: %d, Shift key: %d, Win key: %d, Caps key: %d, Num key: %d\n",
                           (keyState == 1) ? "press" : "release",
                            e.key.keysym.scancode, key, key, e.key.keysym.mod,
                            (e.key.keysym.mod & KMOD_CTRL) ? 1:0,
                            (e.key.keysym.mod & KMOD_ALT) ? 1:0,
                            (e.key.keysym.mod & KMOD_SHIFT) ? 1:0,
                            (e.key.keysym.mod & KMOD_GUI) ? 1:0,
                            (e.key.keysym.mod & KMOD_CAPS) ? 1:0,
                            (e.key.keysym.mod & KMOD_NUM) ? 1:0);
                }
                else
                {
                    printf("%s: e.key.keysym.scancode: %d, e.key.keysym.sym: %d, e.key.keysym.mod: %d; "
                           "Ctrl key: %d, Alt key: %d, Shift key: %d, Win key: %d, Caps key: %d, Num key: %d\n",
                           (keyState == 1) ? "press" : "release",
                            e.key.keysym.scancode, e.key.keysym.sym, e.key.keysym.mod,
                            (e.key.keysym.mod & KMOD_CTRL) ? 1:0,
                            (e.key.keysym.mod & KMOD_ALT) ? 1:0,
                            (e.key.keysym.mod & KMOD_SHIFT) ? 1:0,
                            (e.key.keysym.mod & KMOD_GUI) ? 1:0,
                            (e.key.keysym.mod & KMOD_CAPS) ? 1:0,
                            (e.key.keysym.mod & KMOD_NUM) ? 1:0);
                }
            }
        }

        SDL_RenderClear(sdlrd);
        renderTexture(image, sdlrd, x, y);
        SDL_RenderPresent(sdlrd);
    }

    fprintf(stdout, "Program exit\n");
    SDL_Delay(100);

    SDL_DestroyTexture(image);
    SDL_DestroyRenderer(sdlrd);
    SDL_DestroyWindow(sdlwin);
    IMG_Quit();
    SDL_Quit();

    return EXIT_SUCCESS;

textureRet:
    if (image) SDL_DestroyTexture(image);
    SDL_DestroyRenderer(sdlrd);
renderRet:
    SDL_DestroyWindow(sdlwin);
winRet:
    IMG_Quit();
    SDL_Quit();
initRet:
    return EXIT_FAILURE;
}


/** defgroup MAIN_Exported_Functions
* @}
*/

/** defgroup MAIN
* @}
*/


/***  Copyright (C) 2024 wy1107412334@163.com All rights reserved ***/
/****************************** END OF FILE *************************/

